package com.lhj.xxsc.search.thread;

import java.util.Random;
import java.util.concurrent.*;

/**
 * @author 罗惠江
 * @version 1.0
 * @email 1511619294@qq.com
 * @date 2020/12/21 13:48
 */
public class ThreadTest {
	public static class Thread01 extends Thread {
		@Override
		public void run() {
			System.out.println("当前线程：" + Thread.currentThread().getId());
			int i = 10 / 2;
			System.out.println("运行结果：" + i);
		}
	}

	public static class Thread02 implements Runnable {

		@Override
		public void run() {
			System.out.println("当前线程：" + Thread.currentThread().getId());
			int i = 10 / 2;
			System.out.println("运行结果：" + i);
		}
	}

	public static class Thread03 implements Callable<Integer> {

		@Override
		public Integer call() throws Exception {
			System.out.println("当前线程：" + Thread.currentThread().getId());
			int i = 10 / 2;
			System.out.println("运行结果：" + i);
			return i;
		}
	}


	private static ExecutorService service = Executors.newFixedThreadPool(5);
	/**
	 * 七大参数：
	 * corePoolSize：核心线程数。今天上班人数
	 * maximumPoolSIze：最大线程数。窗口数
	 * keepAliveTime：过期时间。补班人员空闲多久可以走
	 * unit：过期时间单位。
	 * workQueue：等待队列。等待区的位置。
	 * threadFactory：线程创建模式。招工标准。
	 * handler：拒绝策略。人满了保安的工作。
	 */
	ThreadPoolExecutor executor = new ThreadPoolExecutor(
			5,
			200,
			10,
			TimeUnit.SECONDS,
			new LinkedBlockingDeque<>(100000),
			Executors.defaultThreadFactory(),
			new ThreadPoolExecutor.AbortPolicy());

	public static void main(String[] args) throws Exception {
		System.out.println("主线程执行开始");
//		Thread01 thread01 = new Thread01();
//		thread01.start();

//		FutureTask<Integer> futureTask = new FutureTask<>(new Thread03());
//		new Thread(futureTask).start();
//		Integer integer = futureTask.get(); // 阻塞等待
//		System.out.println(integer);
//		service.execute(new Thread01());

//        runAsync();
//        CompletableFuture<Long> future = supplyAsync();
//        whenComplete();
//        thenApply();
//        handle();
//        thenAccept();
//        thenRun();
//        thenCombine();
//        thenAcceptBoth();
//        applyToEither();
//		acceptEither();

		// 异步运行
//		CompletableFuture.runAsync(() -> {
//			System.out.println("当前线程：" + Thread.currentThread().getId());
//			int i = 10 / 2;
//			System.out.println("运行结果：" + i);
//		}, service);
//		CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//			System.out.println("当前线程：" + Thread.currentThread().getId());
//			int i = 10 / 2;
//			System.out.println("运行结果：" + i);
//			return i;
//		}, service).whenCompleteAsync((res, execption) -> {
//			// 虽然能得到异常信息，但是没法修改返回数据
//			System.out.println("异步任务完成完成了。。。结果是：" + res + ";异常是：" + execption);
//		}, service).exceptionally(throwable -> {
//			// 可以感知异常，返回默认值
//			return 10;
//		});

		// 方法执行完成后的处理
//		CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//			System.out.println("当前线程：" + Thread.currentThread().getId());
//			int i = 10 / 2;
//			System.out.println("运行结果：" + i);
//			return i;
//		}, service).handleAsync((res, thr) -> {
//			if (res != null) {
//				return res * 2;
//			}
//			if (thr != null) {
//				return -1;
//			}
//			return 0;
//		}, service);

		// 线程串行化
		// thenRun ：不能得到上一步的执行结果，无返回值
		// thenAccept ：能接收上一步的结果，无返回值
		// thenApply ：能接收上一步结果，有返回值
//		CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//			System.out.println("当前线程：" + Thread.currentThread().getId());
//			int i = 10 / 2;
//			System.out.println("运行结果：" + i);
//			return i;
//		}, service).thenApplyAsync(res -> {
//			System.out.println("xx" + res);
//			return res;
//		}, service);

		/**
		 * 两个都完成了
		 */
//		CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
//			System.out.println("当前线程1：" + Thread.currentThread().getId());
//			int i = 10 / 2;
//			System.out.println("运行结果1：" + i);
//			return i;
//		}, service);
//		CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
//			System.out.println("当前线程2：" + Thread.currentThread().getId());
//			int i = 10 / 2;
//			System.out.println("运行结果2：" + i);
//			return "hello";
//		}, service);
////		future01.runAfterBothAsync(future02, () -> {
////			System.out.println("任务3开始");
////		}, service);
////		future01.thenAcceptBothAsync(future02, (f1, f2) -> {
////			System.out.println("任务3开始" + f1 + "->->->" + f2);
////		}, service);
//
//		CompletableFuture<String> stringCompletableFuture = future01.thenCombineAsync(future02, (f1, f2) -> {
//			return f1 + "===>" + f2;
//		}, service);
//		System.out.println(stringCompletableFuture.get());


		/**
		 * 两个任务中其中有一个
		 * runAfterEitherAsync: 不感知结果，自己也无返回值
		 * acceptEitherAsync: 能感知到结果，无返回值
		 * acceptEitherAsync: 能感知结果，有返回值
		 */
//		future01.runAfterEitherAsync(future02, () -> {
//			System.out.println("任务3开始");
//		}, service);
//		future01.acceptEitherAsync(future02, (res) -> {
//			System.out.println(res);
//		}, service);
//		CompletableFuture<String> huohua = future01.applyToEitherAsync(future02, (res) -> {
//			System.out.println("火化" + res);
//			return "xxx";
//		}, service);
//		System.out.println(huohua.get());

		CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
			System.out.println("查询条件");
			return "holle.jpg";
		}, service);
		CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
			System.out.println("查询条件属性");
			return "黑色+256G";
		}, service);
		CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
			System.out.println("查询商品介绍");
			return "华为";
		}, service);
		// 全部结果返回
		CompletableFuture<Void> allOf = CompletableFuture.allOf(futureAttr, futureDesc, futureImg);
		// 其中一个就行
		CompletableFuture<Object> anyOf = CompletableFuture.anyOf(futureAttr, futureDesc, futureImg);
		allOf.get(); // 等待所有结果执行完
		allOf.join(); // 等待其他结果
		//
		// 阻塞方法
		// Integer integer = future.get();
		// System.out.println(integer);
		System.out.println("主线程执行完成");
	}


	//无返回值
	public static CompletableFuture<Void> runAsync() throws Exception {
		CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
			}
			System.out.println("run end ..." + Thread.currentThread().getId());
		}, service);
//        future.get();
		return future;
	}

	//有返回值
	public static CompletableFuture<Long> supplyAsync() throws Exception {
		CompletableFuture<Long> future = CompletableFuture.supplyAsync(() -> {
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
			}
			System.out.println("run end ...");
			return System.currentTimeMillis();
		});

		return future;
	}

	public static void whenComplete() throws ExecutionException, InterruptedException {
		CompletableFuture<Long> future = CompletableFuture.supplyAsync(() -> {
			try {
				System.out.println("run start ...");
				TimeUnit.SECONDS.sleep(1);
				Long i = 1000L / 0;
			} catch (InterruptedException e) {
			}
			return 1L;
		}, service).whenCompleteAsync((res, exception) -> {
			System.out.println("结果完成" + res);
			System.out.println("出现异常:" + exception);
		}).exceptionally(t -> {
			System.out.println(t.getMessage());
			return 10L;
		});
		System.out.println("run end ..." + future.get());
	}

	private static void thenApply() throws Exception {
		CompletableFuture<Long> future = CompletableFuture.supplyAsync(() -> {
			try {
				System.out.println("run start ...");
				TimeUnit.SECONDS.sleep(1);
				Long i = 1000L / 3;
			} catch (InterruptedException e) {
			}
			return 1L;
		}, service).thenApply(res -> res * 2);
		System.out.println(future.get());
	}

	private static void handle() throws Exception {
		CompletableFuture<Long> future = CompletableFuture.supplyAsync(() -> {
			try {
				System.out.println("run start ...");
				TimeUnit.SECONDS.sleep(1);
				Long i = 1000L / 0;
				return 1L;
			} catch (InterruptedException e) {
				return 2L;
			}
		}, service).handle((t, u) -> {
			System.out.println(u.getMessage());
			return t * 2;
		});
		System.out.println(future.get());
	}

	private static void thenAccept() throws Exception {
		CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
			try {
				System.out.println("run start ...");
				TimeUnit.SECONDS.sleep(1);
				Long i = 1000L / 3;
				return 1L;
			} catch (InterruptedException e) {
				return 2L;
			}
		}, service).thenAccept(res -> {
			System.out.println(res);
		});
//        System.out.println(future.get());
	}

	private static void thenRun() throws Exception {
		CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
			try {
				System.out.println("run start ...");
				TimeUnit.SECONDS.sleep(1);
				Long i = 1000L / 0;
				return 1L;
			} catch (InterruptedException e) {
				e.printStackTrace();
				return -1L;
			}
		}, service).thenRun(() -> {
			System.out.println("thenRun方法执行了，，");
		});
		System.out.println(future.get());
	}

	private static void thenCombine() throws Exception {
		CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "hello1");
		CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "hello2");
		CompletableFuture<String> result = future1.thenCombine(future2, (t, u) -> t + " " + u);
		System.out.println(result.get());
	}

	private static void thenAcceptBoth() throws Exception {
		CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
			int t = new Random().nextInt(3);
			try {
				TimeUnit.SECONDS.sleep(t);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("f1=" + t);
			return t;
		}, service);

		CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
			int t = new Random().nextInt(3);
			try {
				TimeUnit.SECONDS.sleep(t);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("f2=" + t);
			return t;
		}, service);
	}

	private static void applyToEither() throws Exception {
		CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
			int t = new Random().nextInt(3);
			try {
				TimeUnit.SECONDS.sleep(t);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("f1=" + t);
			return t;
		}, service);
		CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
			int t = new Random().nextInt(3);
			try {
				TimeUnit.SECONDS.sleep(t);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("f2=" + t);
			return t;
		}, service);

		CompletableFuture<Integer> result = f1.applyToEither(f2, t -> {
			System.out.println("applyEither:" + t);
			return t * 2;
		});

	}

	private static void acceptEither() throws Exception {
		CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
			int t = new Random().nextInt(3);
			try {
				TimeUnit.SECONDS.sleep(t);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("f1=" + t);
			return t;
		}, service);
		CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
			int t = new Random().nextInt(3);
			try {
				TimeUnit.SECONDS.sleep(t);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("f2=" + t);
			return t;
		}, service);

		CompletableFuture<Void> result = f1.acceptEither(f2, t -> {
			System.out.println("acceptEither:" + t);
		});

	}
}
